package com.cn.kehong.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cn.kehong.api.ILoginLogService;
import com.cn.kehong.api.ILoginService;
import com.cn.kehong.conf.Config;
import com.cn.kehong.dao.LoginMapper;
import com.cn.kehong.domain.Login;
import com.cn.kehong.domain.LoginExample;
import com.cn.kehong.domain.LoginLog;
import com.cn.kehong.utils.*;
import com.cn.kehong.utils.msgSend.HttpClientUtil;
import com.cn.kehong.utils.msgSend.JsonReqClient;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @类名:LoginServiceImpl
 * @包名:com.cn.kehong.service
 * @作者:chenxingliang
 * @时间:2022-11-13 09:16
 * @版本:1.0.0
 */

@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private LoginMapper loginMapper;

    @Autowired
    private ILoginLogService loginLogService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    HttpServletRequest httpServletRequest;

    @Autowired
    private Config config;

    @Override
    public List<Login> getLoginList(QueryForm queryForm) throws Exception {
        return loginMapper.selectUserList(queryForm);
    }

    @Override
    public List<Login> getLoginSelectList() throws Exception {
        LoginExample example = new LoginExample();
        example.createCriteria().andAccountStatusEqualTo(Constants.NORMAL_STATUS).andStatusEqualTo(Constants.NORMAL_STATUS);
        return loginMapper.selectByExample(example);
    }

    @Override
    public List<Login> getLoginAndRoleSelectList() throws Exception {
        return loginMapper.selectUsersWithRole();
    }

    @Override
    public String addLoginDetail(Login login) throws Exception {
        int count = this.countLogin(login.getUserAccount(),"");
        if(count > 0){
            return "账号重复，请重新修改！";
        }
        if(StringUtils.isNotEmpty(login.getPhone())){
            count = this.countLoginPhone(login.getPhone(),"");
            if(count > 0){
                return "手机号重复，请重新修改！";
            }
        }
        String id = CommonUtil.generateRandomNum("login-");
        login.setId(id);
        login.setPassword(MD5Util.MD5(login.getPassword()));
        int addCount = loginMapper.insertSelective(login);
        return CommonUtil.outStr(addCount);
    }

    @Override
    public String updateLoginDetail(Login login) throws Exception {
        String id = login.getId();
        int count = this.countLogin(login.getUserAccount(),id);
        if(count > 0){
            return "账号重复，请重新修改！";
        }
        if(StringUtils.isNotEmpty(login.getPhone())){
            count = this.countLoginPhone(login.getPhone(),id);
            if(count > 0){
                return "手机号重复，请重新修改！";
            }
        }
        LoginExample example = new LoginExample();
        example.createCriteria().andIdEqualTo(id);
        if(StringUtils.equals(login.getResetPwd(),"1")){
            String md5Pwd = MD5Util.MD5("1234567");
            login.setPassword(md5Pwd);
        }
        int updateCount = loginMapper.updateByExampleSelective(login,example);
        return CommonUtil.outStr(updateCount);
    }

    @Override
    public String updatePassword(Login login) throws Exception {
        String oldPassword = login.getOldPassword();
        String id = login.getId();
        String md5Pwd = MD5Util.MD5(oldPassword);
        LoginExample example = new LoginExample();
        example.createCriteria().andIdEqualTo(id).andPasswordEqualTo(md5Pwd);
        int count = loginMapper.countByExample(example);
        if(count == 0){
            return "用户密码不正确！";
        }
        Login update = new Login();
        update.setPassword( MD5Util.MD5(login.getPassword()));
        count = loginMapper.updateByExampleSelective(update,example);
        return CommonUtil.outStr(count);
    }

    @Override
    public String delLoginDetail(QueryForm queryForm) throws Exception {
        List<String> ids = queryForm.getIds();
        if(CollectionsUtil.isEmpty(ids)){
            return "请选择用户";
        }
        Login update = new Login();
        update.setStatus(Constants.DEL_STATUS);
        LoginExample ex = new LoginExample();
        ex.createCriteria().andIdIn(ids);
        int count = loginMapper.updateByExampleSelective(update,ex);
        return CommonUtil.outStr(count);
    }

    @Override
    public String getLoginDetail(Login login) throws Exception {
        String id = login.getId();
        Login queryLogin = loginMapper.selectByPrimaryKey(id);
        if(null == queryLogin){
            return "用户不存在";
        }
        String status = queryLogin.getStatus();
        if(!StringUtils.equals(status,"0")){
            return "用户不存在";
        }
        String accountStatus = queryLogin.getStatus();
        if(!StringUtils.equals(accountStatus,"0")){
            return "用户已被停用";
        }
        String password = queryLogin.getPassword();
        String md5Pwd = MD5Util.MD5(login.getPassword());
        if(!StringUtils.equals(password,md5Pwd)){
            return "密码错误";
        }
        return "";
    }

    @Override
    public Login doLogin(Login login) throws Exception {
        Login result = new Login();
        if(null == login){
            result.setMessage("登陆参数异常！");
            return result;
        }
        String userAccount = login.getUserAccount();
        String password = login.getPassword();
        if(StringUtils.isEmpty(userAccount)|| StringUtils.isEmpty(password)){
            result.setMessage("用户名或者密码为空！");
            return result;
        }
        LoginLog loginLog = new LoginLog();
        loginLog.setUserName(userAccount);
        String md5Pwd = MD5Util.MD5(password);
        Login exist = loginMapper.selectByUserAccount(userAccount);
        if(null == exist){
            loginLog.setMessage(userAccount+" 账号不存在");
            loginLog.setType("1");
            loginLogService.addLoginLogDetail(loginLog);
            result.setMessage("账号不存在！");
            return result;
        }
        String existPwd = exist.getPassword();
        if(!StringUtils.equals(existPwd,md5Pwd)){
            loginLog.setMessage(userAccount+" 密码不正确");
            loginLog.setType("1");
            loginLogService.addLoginLogDetail(loginLog);
            //累计错误登录次数
            loginMapper.updateLoginErrorCount(userAccount);
            result.setMessage("密码不正确！");
            return result;
        }
        if(StringUtils.equals(exist.getAccountStatus(),"1")){
            loginLog.setMessage(userAccount+" 账户已经停用");
            loginLog.setType("1");
            loginLogService.addLoginLogDetail(loginLog);
            result.setMessage("账户已经停用！");
            return result;
        }
        result.setId(exist.getId());
        result.setUserName(exist.getUserName());
        result.setUserAccount(exist.getUserAccount());
        result.setType(exist.getType());
        result.setRoleId(exist.getRoleId());
        String token = generateToken(result);
        result.setToken(token);
        redisTemplate.opsForValue().set(httpServletRequest.getSession().getId(),token);
//        redisTemplate.opsForValue().set(httpServletRequest.getSession().getId(),token, 10,TimeUnit.MINUTES);
        loginLog.setMessage(userAccount+" 登录成功");
        loginLog.setType("0");
        loginLogService.addLoginLogDetail(loginLog);
        return result;
    }

    @Override
    public int countLogin(String loginAccount, String userId) throws Exception {
        LoginExample example = new LoginExample();
        LoginExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(Constants.NORMAL_STATUS).andUserAccountEqualTo(loginAccount);
        if(StringUtils.isNotBlank(userId)){
            criteria.andIdNotEqualTo(userId);
        }
        int count = loginMapper.countByExample(example);
        return count;
    }

    @Override
    public int countLoginPhone(String phone, String userId) throws Exception {
        LoginExample example = new LoginExample();
        LoginExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(Constants.NORMAL_STATUS).andPhoneEqualTo(phone);
        if(StringUtils.isNotBlank(userId)){
            criteria.andIdNotEqualTo(userId);
        }
        int count = loginMapper.countByExample(example);
        return count;
    }

    @Override
    public Map<String, Login> getUserMap() throws Exception {
        LoginExample example = new LoginExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS);
        List<Login> logins = loginMapper.selectByExample(example);
        Map<String,Login> map = Maps.newHashMap();
        for(Login login:logins){
            map.put(login.getId(),login);
        }
        return map;
    }

    @Override
    public Map<String, String> getUserNameMap() throws Exception {
        LoginExample example = new LoginExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS);
        List<Login> logins = loginMapper.selectByExample(example);
        Map<String,String> map = Maps.newHashMap();
        for(Login login:logins){
            map.put(login.getId(),login.getUserName());
        }
        return map;
    }


    @Override
    public Login doLoginByPhone(String user, String password, String code) throws Exception {
        Login login = new Login();
        if(StringUtils.isEmpty(user)){
            login.setMessage("用户不能为空！");
            return login;
        }
//        if(StringUtils.isEmpty(password)&&StringUtils.isEmpty(code)){
//            login.setMessage("缺少必填参数！");
//            return login;
//        }
//        if(StringUtils.isNotEmpty(code)){
//            Object values =  redisTemplate.opsForValue().get(user);
//            if(null == values){
//                login.setMessage("验证码不正确！");
//                return login;
//            }
//        }
        List<Login> logins = loginMapper.selectUserByPhoneOrUserName(user);
        if(CollectionUtils.isEmpty(logins)||logins.size()!= 1){
            login.setMessage("该用户不存在！");
            return login;
        }
        Login exist = logins.get(0);
//        if(!StringUtils.equals(exist.getAppUser(),"1")){
//            login.setMessage("该用户不是app用户！");
//            return login;
//        }
        if(StringUtils.isNotEmpty(password)){
            if(!StringUtils.equals(exist.getPassword(),MD5Util.MD5(password))){
                login.setMessage("密码不正确！");
                return login;
            }
        }
        return exist;
    }

    @Override
    public String sendCode(String phone) throws Exception {
        JsonReqClient jsonReqClient = new JsonReqClient();
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10,5)));
        String param = code+",120";
        String result = jsonReqClient.sendSms(config.sid, config.token, config.appid, config.templateId, param, phone, "");
        System.out.println(result);
        redisTemplate.opsForValue().set(phone,code,120, TimeUnit.SECONDS);
        return code;
    }

    @Override
    public String getLoginNameByWorkNum(String workNum) throws Exception {
        if(StringUtils.isEmpty(workNum)){
            return "";
        }
        LoginExample example = new LoginExample();
        example.createCriteria().andWorkNumEqualTo(workNum).andStatusEqualTo(Constants.NORMAL_STATUS);
        List<Login> logins = loginMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(logins)){
            return "";
        }
        return logins.get(0).getUserName();
    }

    @Override
    public List<Login> getLoginLiaoYuan() throws Exception {
        return loginMapper.selectNormalUsers();
    }

    @Override
    public int batchLoginList(List<Login> loginArrayList) throws Exception {
        return  loginMapper.batchLoginList(loginArrayList);
    }

    private String generateToken(Login login)throws Exception{
        String token  = "";
        JSONObject jsonObject = new JSONObject();
        Date date = new Date();
        long timeStamp = date.getTime();
        jsonObject.put("timeStamp",timeStamp);
        jsonObject.put("id",login.getId());
        jsonObject.put("userAccount",login.getUserAccount());
        jsonObject.put("userName",login.getUserName());
        jsonObject.put("accountType",login.getAccountType());
        token = jsonObject.toJSONString();
        token = MD5Util.getEncoder(token);
        return token;
    }
}
